package com.arsProfundis.dal.mongo.mappings


import com.mongodb.DBObject
import com.mongodb.casbah.Imports._

import com.arsProfundis.dal.mappers._

object Properties {

	trait Property[A, B <: Any] {
		val name: String
		val mapper: Mapper[A, B]
                      
		protected implicit val manifestA: Manifest[A]
		protected implicit val manifestB: Manifest[B]
	}

	trait MondatoryProperty[A, B <: Any] extends Property[A, B] {
		def apply(value: A): Tuple2[String, B] = { 
			name -> mapper.apply(value) 
		}
		def apply(value: DBObject): A = {
			value.getAs[B](name).map(b => mapper.unapply(b)).getOrElse(throw new Exception(name))
		}
	}

	case class SingleValueMondatoryProperty[A, B <: Any](name: String, mapper: Mapper[A, B])(implicit val manifestA: Manifest[A], 
																														implicit val manifestB: Manifest[B]) 
																														extends MondatoryProperty[A, B]
	

	def mondatoryProperty[A, B <: Any](name: String, dataType: Mapper[A, B])(implicit manifestA: Manifest[A], 
																												manifestB: Manifest[B]) = {
		new SingleValueMondatoryProperty[A, B](name, dataType)
	}
}